home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / zoo21src.zoo / vms.c < prev    next >
C/C++ Source or Header  |  1991-07-24  |  11KB  |  387 lines

  1. #ifndef LINT
  2. /* derived from: @(#) vms.c 2.2 88/01/09 03:47:52 */
  3. static char vmsid[]="$Source$\n\
  4. $Id$";
  5. #endif /* LINT */
  6.  
  7. /* Support routines for VAX/VMS. */
  8.  
  9. #include <stat.h>
  10. #include <time.h>
  11.  
  12. /* our own version of NULL; avoid any interaction with system defn.
  13. but don't require inclusion of stdio.h */
  14. #define  NILPTR    0
  15.  
  16. /* Function isuadir() returns 1 if the supplied filename is a directory, 
  17. else it returns 0.  
  18. */
  19.  
  20. int isuadir (file)
  21. char *file;
  22. {
  23.    struct stat buf;           /* buffer to hold file information */
  24.    if (stat (file, &buf) == -1) {
  25.       return (0);             /* inaccessible -- assume not dir */
  26.    } else {
  27.       if (buf.st_mode & S_IFDIR)
  28.          return (1);
  29.       else
  30.          return (0);
  31.    }
  32. }
  33.  
  34. /****************
  35. Function fixfname() converts the supplied filename to a syntax
  36. legal for the host system.  It is used during extraction.  We
  37. allow a maximum of one dot in the filename, and it must not
  38. be at the beginning.  We also truncate the number of charac-
  39. ters preceding and following the dot to at most 39.
  40. */
  41.  
  42. char *strchr();
  43.  
  44. char *fixfname(fname)
  45. char *fname;
  46. {
  47.    char *p;
  48.    char *dotpos;
  49.    static char legal[] = 
  50.       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_.0123456789";
  51.  
  52.    /* convert all characters to legal characters */
  53.    for (p = fname;  *p != '\0';  p++)
  54.       if (strchr (legal, *p) == 0) {
  55.          if (*p == '-' || *p == ' ')
  56.             *p = '_';
  57.          else
  58.             *p = legal [ *p % 26 ];
  59.       }
  60.  
  61.    /* first char can't be dot */
  62.    if (*fname == '.')
  63.       *fname = 'X';
  64.  
  65.    /* find embedded dot if any */
  66.    dotpos = strchr (fname, '.');
  67.  
  68.    if (dotpos != NILPTR) {
  69.       for (p = dotpos+1;  *p != '\0';  p++)  /* remove 2nd dot onwards */
  70.          if (*p == '.')
  71.             *p = '_';
  72.       if (dotpos - fname + 1 > 39) {  /* more than 39 before dot not allowed */
  73.          char *q;
  74.          p = fname + 39;
  75.          q = dotpos;
  76.          while (*p++ = *q++)  /* the notational convenience is considerable */
  77.             ;
  78.          dotpos = strchr (fname, '.');
  79.       }
  80.       if (strlen (dotpos + 1) > 39)  /* more than 39 after dot not allowed */
  81.          *(dotpos + 39 + 1) = '\0';
  82.    } else
  83.       *(fname + 39) = '\0'; /* no dots, just truncate to 39 characters */
  84.    return (fname);
  85. }
  86.  
  87. /*
  88. Function gettz(), returns the offset from GMT in seconds of the
  89. local time, taking into account daylight savings time -- or it
  90. would, if VAX/VMS knew about timezones!  It's just a no-op.
  91. */
  92. long gettz()
  93. {
  94.    return 0L;
  95. }
  96.  
  97. struct tm *localtime();
  98.  
  99. /*****************
  100. Function gettime() gets the date and time of the file handle supplied.
  101. Date and time is in MSDOS format.  This function duplicated from nixtime.i.
  102. */
  103.  
  104. int gettime (file, date, time)
  105. ZOOFILE file;
  106. unsigned *date, *time;
  107. {
  108.    struct stat buf;           /* buffer to hold file information */
  109.    struct tm *tm;             /* will hold year/month/day etc. */
  110.     int handle;
  111.     handle = fileno(file);
  112.    if (fstat (handle, &buf) == -1) {
  113.       prterror ('w', "Could not get file time\n");
  114.       *date = *time = 0;
  115.    } else {
  116.       tm = localtime (&buf.st_mtime); /* get info about file mod time */
  117.       *date = tm->tm_mday + ((tm->tm_mon + 1) << 5) +
  118.          ((tm->tm_year - 80) << 9);
  119.       *time = tm->tm_sec / 2 + (tm->tm_min << 5) +
  120.          (tm->tm_hour << 11);
  121.    }
  122.  
  123. }
  124.  
  125. /*
  126. Function unlink() will delete a file using the VMS C delete()
  127. function.
  128. */
  129. int unlink (fname)
  130. char *fname;
  131. {
  132.    return (delete (fname));
  133. }
  134.  
  135. /*
  136. Function zooexit() receives attempts at exit.  It always invokes
  137. exit() with status=1.
  138. */
  139. void zooexit (status)
  140. int status;
  141. {
  142.    exit (1);
  143. }
  144.  
  145.  
  146. /*
  147. Function rename() renames a file.  
  148. Thanks to Owen Anthony (was <anthony@bsu-cs.bsu.edu> at one time).
  149. */
  150.  
  151. #include <descrip.h>
  152.  
  153. #ifdef NEED_VMS_RENAME /* if not using VMS 4.6 library rename() */
  154. int rename (old_name, new_name)
  155. char *old_name;
  156. char *new_name;
  157. {
  158.    int status;
  159.    struct dsc$descriptor_s file1, file2;
  160.    file1.dsc$w_length = strlen (old_name);  /* descriptor for old name */
  161.    file1.dsc$a_pointer = old_name;
  162.    file1.dsc$b_class = DSC$K_CLASS_S;
  163.    file1.dsc$b_dtype = DSC$K_DTYPE_T;
  164.    file2.dsc$w_length = strlen (new_name);  /* descriptor for new name */
  165.    file2.dsc$a_pointer = new_name;
  166.    file2.dsc$b_class = DSC$K_CLASS_S;
  167.    file2.dsc$b_dtype = DSC$K_DTYPE_T;
  168.  
  169.    status = LIB$RENAME_FILE (&file1, &file2);
  170.  
  171.    return ((status & ~1) == 1);
  172. }
  173. #endif /* VMS_RENAME */
  174.  
  175. /*
  176. Function specfname() modifies filenames before they are stored
  177. in an archive.  Currently we remove any trailing version field,
  178. and then any trailing dot.
  179. */
  180. char *specfname (fname)
  181. char *fname;
  182. {
  183.    char *p;
  184.    p = strchr (fname, ';');
  185.    if (p != NILPTR)
  186.       *p = '\0';
  187.    if (*fname != '\0') {
  188.       p = fname + strlen (fname) - 1; /* point to last char */
  189.       if (*p == '.')                  /* remove any trailing dot */
  190.          *p = '\0';
  191.    }
  192.    return (fname);
  193. }
  194.  
  195. /* 
  196. Function specdir() modifies directory names before they are stored
  197. in an archive.  We remove any leading device name or logical
  198. name and and the [ and ] that bracket any directory name.
  199. Then we change any dots in the directory name to slashes.
  200. */
  201.  
  202. #if 0
  203. /* test stub that just truncates dir to null string */
  204. char *specdir (fname) char *fname;
  205. { *fname = '\0'; return (fname); }
  206. #else
  207.  
  208. char *specdir (fname)
  209. char *fname;
  210. {
  211.    char *p;
  212.    char tmpstr[LFNAMESIZE];
  213.  
  214.    p = strchr (fname, ':');      /* remove chars upto and including : */
  215.    if (p != NILPTR) {
  216.       strcpy (tmpstr, p+1);
  217.       strcpy (fname, tmpstr);
  218.    }
  219.  
  220.    p = strchr (fname, '[');      /* remove chars upto and including [ */
  221.    if (p != NILPTR) {
  222.       strcpy (tmpstr, p+1);
  223.       strcpy (fname, tmpstr);
  224.    }
  225.  
  226.    p = strchr (fname, ']');      /* truncate at ] */
  227.    if (p != NILPTR) {
  228.       if (*(p+1) != '\0')
  229.          prterror ('w', "Trailing garbage in directory name\n");
  230.       *p = '\0';
  231.    }
  232.  
  233.    for (p = fname;  *p != '\0';  p++)   /* change dots to slashes */
  234.       if (*p == '.')
  235.          *p = '/';
  236.  
  237.    /* make sure there is a leading slash -- just a hack for now */
  238.    if (*fname != '/') {
  239.       strcpy (tmpstr, fname);
  240.       strcpy (fname, "/");
  241.       strcat (fname, tmpstr);
  242.    }
  243.  
  244. #ifdef DEBUG
  245. printf ("dir name transformed to \"%s\"\n", fname);
  246. #endif
  247. }
  248. #endif
  249.  
  250. #define  FMAX  3        /* Number of different filename patterns */
  251.  
  252. char *nextfile (what, filespec, fileset)
  253. int what;                        /* whether to initialize or match      */
  254. register char *filespec;         /* filespec to match if initializing   */
  255. register int fileset;            /* which set of files                  */
  256. {
  257.    int status;
  258.    char *p;                      /* temp ptr */
  259.    struct dsc$descriptor_s d_fwild, d_ffound;
  260.    static int first_time [FMAX+1];
  261.    static char saved_fspec [FMAX+1][PATHSIZE];  /* our own copy of filespec */
  262.    static char found_fspec [FMAX+1][PATHSIZE];  /* matched filename */
  263.    static unsigned long context [FMAX+1];    /* needed by VMS */
  264.    if (what == 0) {
  265.       strcpy (saved_fspec[fileset], filespec);  /* save the filespec */
  266.       first_time[fileset] = 1;
  267.       return (0);
  268.    }
  269.  
  270.    /* Reach here if what is not 0, so it must be 1 */
  271.  
  272.    /* Create a descriptor for the wildcarded filespec */
  273.    d_fwild.dsc$w_length = strlen (saved_fspec[fileset]);
  274.    d_fwild.dsc$a_pointer = saved_fspec[fileset];
  275.    d_fwild.dsc$b_class = DSC$K_CLASS_S;
  276.    d_fwild.dsc$b_dtype = DSC$K_DTYPE_T;
  277.  
  278.    d_ffound.dsc$w_length = sizeof (found_fspec[fileset]);
  279.    d_ffound.dsc$a_pointer = found_fspec[fileset];
  280.    d_ffound.dsc$b_class = DSC$K_CLASS_S;
  281.    d_ffound.dsc$b_dtype = DSC$K_DTYPE_T;
  282.  
  283.    if (first_time[fileset]) {
  284.       first_time[fileset] = 0;
  285.       context[fileset] = 0L;   /* tell VMS this is first search */
  286.    }
  287.    status = LIB$FIND_FILE (&d_fwild, &d_ffound, &context[fileset]);
  288.    status = status & 1;    /* use only lowest bit */
  289.  
  290.    if (status == 0) {
  291.       LIB$FIND_FILE_END (&context[fileset]);
  292.       return ((c